'''Notifies using libnotify.'''

import logging
import threading

import pynotify
import gobject

from statusnotifications.notifier import Notifier

LOGGER = logging.getLogger('statusnotifications.notifier.libnotify')
pynotify.init('status-notifications')

class LibNotifyNotifier(Notifier):
    '''Libnotify implementation.'''

    name = 'libnotify'

    def __init__(self, config):
        '''Create a notifier.'''

        Notifier.__init__(self, config)
        self._gobject_main_thread = GobjectMainThread()
        self._gobject_main_thread.setDaemon(True)
        self._gobject_main_thread.start()

        self.seq = NotificationsSequencer()

    def notify(self, status):
        '''Notify of the status.'''

        Notifier.notify(self, status)

        title = "%s: %s" % (status.service_name, status.user.name)
        msg = status.message
        image = 'file://' + status.user.image
        notif = pynotify.Notification(title.encode('utf8'), msg.encode('utf8'),
                                      image)
        notif.set_urgency(pynotify.URGENCY_LOW)
        if self.config['timeout']:
            notif.set_timeout(self.config['timeout'] * 1000)
        else:
            notif.set_timeout(pynotify.EXPIRES_NEVER)

        for i in range(self.config['times']):
            self.seq.show(notif)

class NotificationsSequencer(object):
    '''Shows notifications in a sequence.'''

    def __init__(self):
        self.queue = []

    def show(self, notification):
        '''Show or enqueue if theres already a notification being shown.'''

        self.queue.append(notification)
        if len(self.queue) == 1:
            LOGGER.debug("Showing notification %s" % notification)
            notification.connect('closed', self.on_close)
            notification.show()

    def on_close(self, notification):
        '''Remove the notification being shown and show the next one.'''

        last_notification = self.queue.pop(0)
        LOGGER.debug("Notification %s was closed" % last_notification)
        assert last_notification == notification

        if self.queue:
            LOGGER.debug("Showing notification %s" % self.queue[0])
            self.queue[0].connect('closed', self.on_close)
            self.queue[0].show()

gobject.threads_init()
class GobjectMainThread(threading.Thread):
    '''Runs the GObject main loop in a thread.'''

    def run(self):
        '''Create and run a main loop.'''

        loop = gobject.MainLoop()
        loop.run()

